﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics;
using DreamOnGameEngine.Utils;
using System.Threading;
using System.Runtime.InteropServices;
using System.Management;
using DreamOnGameEngine.ErrorHandling;
namespace DreamOnGameEngine
{
    public class DreamOnApp:GameWindow
    {
        public DreamOnApp(int width,int height,GraphicsMode GraphicsMode,string Title)
            : base(width,height,GraphicsMode,Title)
        {
        }
        const int MEGABYTE = 1024 * 1024;
        const ulong physicalRAM = 32 * MEGABYTE;
        const ulong virtualRAM = 64 * MEGABYTE;
        const ulong diskSpace = 10 * MEGABYTE;
        const ulong cpuSpeed = 1000;
        bool InitInstance(CommandLine CmdLine, int? Handle = null, int ScreenWidth = 800, int ScreenHeight = 600)
        {
#if !DEBUG
            if(!IsOnlyInstance(VGameTitle))
                return false;
#endif
            Localization.Localization.PrefixDir = "Data\\lang\\";
            Localization.Localization.Locale = Thread.CurrentThread.CurrentCulture.ToString();
            if (!Localization.Localization.Load("General.xml"))
            {
                MessageBox.Show("Error 6502: Language  not found ( "+Localization.Localization.Locale+" ).\r\n\r\nPlease reinstall from your original CD.", "Error 6502", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            bool resourceCheck = false;
            while (!resourceCheck)
	        {
                try
                {

                    CheckMemory(physicalRAM, virtualRAM);
                    CheckDiskspace(diskSpace);
                    CheckCPU(cpuSpeed);
                }
                catch (GameError e)
                {
                }
                
        }
            Cursor.Hide();
            return true;
        }

        private void CheckCPU(ulong speed)
        {
            ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'");
            uint sp = (uint)(Mo["CurrentClockSpeed"]);
            Mo.Dispose();
            if (speed > sp)
                throw new GameError();

        }
        [DllImport("kernel32", CharSet = CharSet.Auto)]
        static extern int GetDiskFreeSpaceEx(
         string lpDirectoryName,
         out ulong lpFreeBytesAvailable,
         out ulong lpTotalNumberOfBytes,
         out ulong lpTotalNumberOfFreeBytes);
        private void CheckDiskspace(ulong diskSpace)
        {
            ulong freeBytesAvailable, totalBytes, freeBytes;

            // Call the Win32 API to retrieve disk space information.
            GetDiskFreeSpaceEx("C:", out freeBytesAvailable, out totalBytes, out freeBytes);
            if (diskSpace > freeBytesAvailable)
                throw new GameError();
        }
        private void CheckMemory(ulong physicalRAM, ulong virtualRAM)
        {
            ulong installedPhysical;
            ulong virtualMem;
            Initialize.MEMORYSTATUSEX memStatus = new Initialize.MEMORYSTATUSEX();
            if (Initialize.GlobalMemoryStatusEx(memStatus))
            {
                installedPhysical = memStatus.ullTotalPhys;
                virtualMem = memStatus.ullTotalVirtual;
            }
            else
            {
                throw new GameError();
            }
            if (installedPhysical < physicalRAM)
                throw new GameError();
            if (virtualMem < virtualRAM)
                throw new GameError();
        }
        public static string GetGameTitle()
        {
            return "Dream On Game Engine";
        }
        public static bool InitDreamApp(CommandLine CmdLine)
        {
            int width = (CmdLine["width"] != null) ? int.Parse(CmdLine["width"]) : 800;
            int height = (CmdLine["height"] != null) ? int.Parse(CmdLine["height"]) : 600;
            string title = GetGameTitle();
            using (DreamOnApp app = new DreamOnApp(width,height,GraphicsMode.Default,title))
            {
                app.InitInstance(CmdLine);
                app.Run(30.0);
            }
            return true;
        }
    }
}
